/**
 * 
 */
package cn.agiledata.bank.account.dao.hibernate;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import cn.agiledata.bank.account.dao.ISequenceDAO;
import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.hibernateBean.Sequence;


/**
 * @author 马贤波
 *
 * Apr 6, 2006
 */
public class HibernateSequenceDAO  extends HibernateDaoSupport implements ISequenceDAO {

	private static Log log = LogFactory.getLog(HibernateSequenceDAO.class);
	
	public synchronized String retrieveSeqByType(String type) throws DataAccessException {
		
		if (type == null) {
			throw new DataIntegrityViolationException ("invalided type :type cannot be NULL ") ;
		}
		DateFormat df = null;
		String month = null;
		if(type.equals(Constant.ID_ACCOUNT)) { //如果是账户顺序号
			df = new SimpleDateFormat("yyyyMMddHHmmss") ;
			month = df.format(new Date()) ;	
			String queryString = "from Sequence s where s.type=:type " ;
			String[] paramNames = {"type"} ;
			Object[] values = {type} ;

			List result = this.getHibernateTemplate().findByNamedParam(queryString, paramNames, values) ;
			
			int seqNum = 1 ;
			
			if (result == null || result.size() < 1) {	 
				//尚未有该记录
				Sequence seq = new Sequence () ;
				seq.setType(type) ;
				seq.setMonth(month) ;
				seq.setMax(1) ;
				saveOrUpdateSeq(seq);
			} else {
				Sequence maxSeq = (Sequence) result.get(0) ;
				if(maxSeq.getMonth().equals(month)) { //如果当前日期相同，则叠加
					seqNum = maxSeq.getMax() + 1 ;
					maxSeq.setMax(seqNum) ;
				} else {//如果当前日期不同，重设日期和顺序数
					seqNum = 1;
					maxSeq.setMonth(month);
					maxSeq.setMax(seqNum) ;
				}
				saveOrUpdateSeq(maxSeq);
			}			
			String seqStr = "000" + String.valueOf(seqNum) ;
			seqStr = seqStr.substring(seqStr.length() - 3) ;
			
	 		log.info("取得序列号：" + seqStr) ;
	 		String rtn = month + seqStr ;
			
			return rtn;
		//回单
		} else if(type.equals(Constant.ID_PAY_PAPER) || type.equals(Constant.ID_RECEIVE_PAPER) || type.equals(Constant.ID_TRANSFER_PAPER)) {
			df = new SimpleDateFormat("yyyy") ;
			month = df.format(new Date()) ;
			String queryString = "from Sequence s where s.type=:type and s.month=:month" ;
			String[] paramNames = {"type", "month"} ;
			Object[] values = {type, month} ;

			List result = this.getHibernateTemplate().findByNamedParam(queryString, paramNames, values) ;
			
			int seqNum = 1 ;
			
			if (result == null || result.size() < 1) {	 
				//尚未有该记录
				Sequence seq = new Sequence () ;
				seq.setType(type) ;
				seq.setMonth(month) ;
				seq.setMax(1) ;
				saveOrUpdateSeq(seq);
			} else {
				Sequence maxSeq = (Sequence) result.get(0) ;
				seqNum = maxSeq.getMax() + 1 ;
				maxSeq.setMax(seqNum) ;
				saveOrUpdateSeq(maxSeq);
			}
			
			return String.valueOf(seqNum);
		} else { //如果是其他顺序号
			//df = new SimpleDateFormat("yyyyMM") ;

			df = new SimpleDateFormat("yyyyMMdd") ;

			month = df.format(new Date()) ;
			String queryString = "from Sequence s where s.type=:type and s.month=:month" ;
			String[] paramNames = {"type", "month"} ;
			Object[] values = {type, month} ;

			List result = this.getHibernateTemplate().findByNamedParam(queryString, paramNames, values) ;
			
			int seqNum = 1 ;
			
			if (result == null || result.size() < 1) {	 
				//尚未有该记录
				Sequence seq = new Sequence () ;
				seq.setType(type) ;
				seq.setMonth(month) ;
				seq.setMax(1) ;
				saveOrUpdateSeq(seq);
			} else {
				Sequence maxSeq = (Sequence) result.get(0) ;
				seqNum = maxSeq.getMax() + 1 ;
				maxSeq.setMax(seqNum) ;
				saveOrUpdateSeq(maxSeq);
			}
			String seqStr = "000000" + String.valueOf(seqNum) ;
			seqStr = seqStr.substring(seqStr.length() - 6) ;
			
			log.info("取得序列号：" + seqStr) ;
			
			return seqStr;
		}
	}
	
	/**
	 * 
	 * @param seq
	 */
	public void saveOrUpdateSeq(Sequence seq) {
		this.getHibernateTemplate().save(seq) ;
		this.getHibernateTemplate().flush();
		this.getHibernateTemplate().evict(seq);
	}

}
